#include <iostream>
#include <fstream>
#include <string>
#include <math.h>
#include <time.h>
#include <float.h>
#include "SDL.h"
#include "SDL_opengl.h"
#include "Vector3D.h"
#include "Quaternion.h"
const int width=800;
const int height=600;
bool keys[SDLK_LAST]={0};
Vector3D light_pos(0,10,0);
double* array=NULL;
int n=4,szx=2;
void DrawRect(double h){
	glBegin(GL_QUADS);
	glNormal3d( 0, 0,-0.5);
	glVertex3d(-0.5, h,-0.5);	//Back
	glVertex3d( 0.5, h,-0.5);
	glVertex3d( 0.5,0,-0.5);
	glVertex3d(-0.5,0,-0.5);
	glNormal3d(-0.5, 0, 0);
	glVertex3d(-0.5, h,-0.5);	//Right
	glVertex3d(-0.5,0,-0.5);
	glVertex3d(-0.5,0, 0.5);
	glVertex3d(-0.5, h, 0.5);
	if(h>0)glNormal3d( 0,0.5, 0);
	else glNormal3d( 0,-0.5, 0);
	glVertex3d( 0.5, h,-0.5);	//Top
	glVertex3d(-0.5, h,-0.5);
	glVertex3d(-0.5, h, 0.5);
	glVertex3d( 0.5, h, 0.5);
	glNormal3d( 0, 0, 0.5);
	glVertex3d(-0.5, h, 0.5);	//Front
	glVertex3d(-0.5,0, 0.5);
	glVertex3d( 0.5,0, 0.5);
	glVertex3d( 0.5, h, 0.5);
	glNormal3d( 0.5, 0, 0);
	glVertex3d( 0.5, h,-0.5);	//Left
	glVertex3d( 0.5, h, 0.5);
	glVertex3d( 0.5,0, 0.5);
	glVertex3d( 0.5,0,-0.5);
	if(h>0)glNormal3d( 0,-0.5, 0);
	else glNormal3d( 0,0.5, 0);
	glVertex3d( 0.5,0,-0.5);	//Bottom
	glVertex3d( 0.5,0, 0.5);
	glVertex3d(-0.5,0, 0.5);
	glVertex3d(-0.5,0,-0.5);
	glEnd();
}
inline void DrawScene(){
	static double angle=0.0;
	angle+=0.005;
	gluLookAt(25.5*cos(angle),5,25.5*sin(angle),0,0,0,0,1,0);
	for(int i=0;i<n;i++){
		glPushMatrix();
		glTranslated(i/szx,0,(i%szx));
		DrawRect(array[i]);
		glPopMatrix();
	}
}
int main (int argc, char ** argv) {
	if (argc==3){
		if(argv[1][1]=='f'){
			fstream f(argv[2]);
			f>>n;
			array=new double[n];
			for(int i=0;i<n;i++){
				for(int j=0;j<n;j++){
					double temp=0;
					f>>temp;
					array[i]+=temp*temp;
				}
				array[i]=sqrt(array[i]);
			}
		}
	}
	else{ printf("Usage: %s -f <filename>\n", argv[0]); return 1;}
	if (SDL_Init(SDL_INIT_VIDEO) < 0) exit(1);		//Init SDL
	SDL_WM_SetCaption("Metaballs3D", "Metaballs3D");	//Title and icon(?) captions
	const SDL_VideoInfo *video = SDL_GetVideoInfo();	//Get current video info (for pixel format later)
	if (!video) { SDL_Quit(); exit(1); }
	SDL_Surface *screen = SDL_SetVideoMode(width, height, video->vfmt->BitsPerPixel, SDL_OPENGL);	//Setup video
	if (!screen) { SDL_Quit(); exit(1); }
	glViewport(0, 0, width, height);			//Setup the entire window as a viewport
	
	glDisable(GL_CULL_FACE);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_DEPTH_TEST);
	//glDisable(GL_DEPTH_TEST);  //Might want to for various reasons (2D, alpha etc).
	glDepthMask(GL_TRUE);
	glClearDepth(1.0);
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_SMOOTH);
	//Lighting
	glLightfv(GL_LIGHT1, GL_AMBIENT, (GLfloat[4]){0.5,0.5,0.5,1.0});
	glLightfv(GL_LIGHT1, GL_DIFFUSE, (GLfloat[4]){1.0,1.0,1.0,1.0});
	glLightfv(GL_LIGHT1, GL_POSITION,(GLfloat[4]){light_pos[0],light_pos[1],light_pos[2],1.0});
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHTING);
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, (GLfloat[3]){1,0,0});
	glColor3d(1,0,0);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,1.0f,100.0f); //3D
	//glOrtho(0,width,height,0,0,1);	//2D
	glMatrixMode (GL_MODELVIEW);
	glLoadIdentity();
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);   		// Set Pixel Format
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	bool done=false;
	while(!done){
		SDL_Event event;
		if(SDL_PollEvent(&event)){	//Get an event
			switch (event.type){
				case SDL_KEYDOWN:
					switch(event.key.keysym.sym){
						case SDLK_ESCAPE:
							done=true; continue;
						default:	//Any keys pressed, it'll be true in the global array.
							keys[event.key.keysym.sym]=true; break;
					}
					break;
				case SDL_KEYUP:			//If let up, it'll be false in the array
					keys[event.key.keysym.sym]=false; break;
				case SDL_MOUSEBUTTONDOWN:
					break;
				case SDL_QUIT:			//Window quits
					done=true; continue;
				default:
					break;
			}
		}
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);	//Clear the screen
		glLoadIdentity();		//Reset model matrix.
		DrawScene();
		SDL_GL_SwapBuffers();		//Swap the buffer to the screen
	}
	SDL_Quit();
	return 0;
}
